﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace SMARTMobile.WinPhone.Models
{
    public abstract class BaseModel<TModel> : NotifyingObject
    {
        #region Fields

        private State _modelState;

        private TModel _entity;

        #endregion

        #region Properties

        [XmlIgnore]
        public TModel Entity
        {
            get
            {
                return this._entity;
            }
            set
            {
                this._entity = value;
            }
        }

        [XmlIgnore]
        public State ModelState
        {
            get
            {
                return this._modelState;
            }
            set
            {
                if (this._modelState == value)
                {
                    return;
                }

                this._modelState = value;
                //// Don't rise event PropertyChanged here, it will make an infinite loop
            }
        }

        #endregion

        #region Public methods

        // Invoke the event
        public void RaisePropertyChanged<TResult>(Expression<Func<TModel, TResult>> action)
        {
            var propertyName = ((MemberExpression)action.Body).Member.Name;
            this.RaisePropertyChanged(propertyName);
        }

        public void RaisePropertyChanged(string propertyName)
        {
            if (this.ModelState == State.Unchanged && !string.IsNullOrWhiteSpace(propertyName) && !propertyName.Equals("IsExpanded") && !propertyName.Equals("IsSelected"))
            {
                this.ModelState = State.Modified;
            }

            base.NotifyPropertyChanged(propertyName);
            //if (this.PropertyChanged != null)
            //{
            //    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            //}
        }

        public virtual void AcceptChanged()
        {
        }
        #endregion

        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}